<!doctype html>




<html class="theme-next pisces" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>



<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />












  
  
    
  
  <link href="//cdn.staticfile.org/fancybox/2.1.5/jquery.fancybox.min.css" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  
    
      
    

    
  

  

  
    
      
    

    
  

  
    
      
    

    
  

  
    
    
    <link href="//fonts.lug.ustc.edu.cn/css?family=Monda:300,300italic,400,400italic,700,700italic|Roboto Slab:300,300italic,400,400italic,700,700italic|Lobster Two:300,300italic,400,400italic,700,700italic|PT Mono:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






  

<link href="//cdn.staticfile.org/font-awesome/4.6.2/css/font-awesome.min.css" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.0" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="Web,JavaScript," />








  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.1.0" />






<meta name="description" content="基本类型和引用类型的值基本数据类型： Undefined 、 Null 、 Boolean 、 Number 和 String 。基本类型值在内存中占据固定大小的空间，因此被保存在栈内存中。从一个变量向另一个变量复制基本类型的值，会创建这个值的一个副本。
引用类型的值是保存在内存中的对象(Object)。引用类型的值是对象，保存在堆内存中。包含引用类型值的变量实际上包含的并不是对象本身，而是一个指">
<meta property="og:type" content="article">
<meta property="og:title" content="《 JavaScript 高级程序设计》备忘-第四章">
<meta property="og:url" content="http://codingme.xyz/2016/09/17/javascript-note-04/index.html">
<meta property="og:site_name" content="CodingMe">
<meta property="og:description" content="基本类型和引用类型的值基本数据类型： Undefined 、 Null 、 Boolean 、 Number 和 String 。基本类型值在内存中占据固定大小的空间，因此被保存在栈内存中。从一个变量向另一个变量复制基本类型的值，会创建这个值的一个副本。
引用类型的值是保存在内存中的对象(Object)。引用类型的值是对象，保存在堆内存中。包含引用类型值的变量实际上包含的并不是对象本身，而是一个指">
<meta property="og:updated_time" content="2016-10-15T09:47:12.933Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="《 JavaScript 高级程序设计》备忘-第四章">
<meta name="twitter:description" content="基本类型和引用类型的值基本数据类型： Undefined 、 Null 、 Boolean 、 Number 和 String 。基本类型值在内存中占据固定大小的空间，因此被保存在栈内存中。从一个变量向另一个变量复制基本类型的值，会创建这个值的一个副本。
引用类型的值是保存在内存中的对象(Object)。引用类型的值是对象，保存在堆内存中。包含引用类型值的变量实际上包含的并不是对象本身，而是一个指">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Pisces',
    sidebar: {"position":"right","display":"post"},
    fancybox: true,
    motion: false,
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://codingme.xyz/2016/09/17/javascript-note-04/"/>





  <title> 《 JavaScript 高级程序设计》备忘-第四章 | CodingMe </title>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  










  
  
    
  

  <div class="container one-collumn sidebar-position-right page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-meta ">
  

  <div class="custom-logo-site-title">
    <a href="/"  class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <span class="site-title">CodingMe</span>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>
  <p class="site-subtitle"></p>
</div>

<div class="site-nav-toggle">
  <button>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
  </button>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      

      
        <li class="menu-item menu-item-search">
          
            <a href="javascript:;" class="popup-trigger">
          
            
              <i class="menu-item-icon fa fa-search fa-fw"></i> <br />
            
            搜索
          </a>
        </li>
      
    </ul>
  

  
    <div class="site-search">
      
  <div class="popup">
 <span class="search-icon fa fa-search"></span>
 <input type="text" id="local-search-input">
 <div id="local-search-result"></div>
 <span class="popup-btn-close">close</span>
</div>


    </div>
  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
  <link itemprop="mainEntityOfPage" href="http://codingme.xyz/2016/09/17/javascript-note-04/">

  <span style="display:none" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <meta itemprop="name" content="Huang SJ">
    <meta itemprop="description" content="">
    <meta itemprop="image" content="/uploads/avatar.jpg">
  </span>

  <span style="display:none" itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
    <meta itemprop="name" content="CodingMe">
    <span style="display:none" itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
      <img style="display:none;" itemprop="url image" alt="CodingMe" src="">
    </span>
  </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
            
            
              
                《 JavaScript 高级程序设计》备忘-第四章
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">
            

            

            
          </span>

          

          
            
          

          

          
          

          

          

        </div>
      </header>
    


    <div class="post-body" itemprop="articleBody">

      
      

      
        <h1 id="基本类型和引用类型的值"><a href="#基本类型和引用类型的值" class="headerlink" title="基本类型和引用类型的值"></a>基本类型和引用类型的值</h1><p>基本数据类型： Undefined 、 Null 、 Boolean 、 Number 和 String 。<br>基本类型值在内存中占据固定大小的空间，因此被保存在栈内存中。<br>从一个变量向另一个变量复制基本类型的值，会创建这个值的一个副本。</p>
<p>引用类型的值是保存在内存中的对象(Object)。<br>引用类型的值是对象，保存在堆内存中。<br>包含引用类型值的变量实际上包含的并不是对象本身，而是一个指向该对象的指针。<br>从一个变量向另一个变量复制引用类型的值，复制的其实是指针，因此两个变量最终都指向同一个对象。</p>
<p>JavaScript 不允许直接访问内存中的位置，也就是说不能直接操作对象的内存空间。<br>在操作对象时，实际上是在操作对象的引用而不是实际的对象。<br>为此，引用类型的值是按引用访问的。(当复制保存着对象的某个变量时，操作的是对象的引用。但在为对象添加属性时，操作的是实际<br>的对象。)</p>
<p>在很多语言中，字符串以对象的形式来表示，因此被认为是引用类型的。<br>ECMAScript 放弃了这一传统。</p>
<h2 id="动态的属性"><a href="#动态的属性" class="headerlink" title="动态的属性"></a>动态的属性</h2><p>对于引用类型的值，我们可以为其添加属性和方法，也可以改变和删除其属性和方法。(Object)<br>只能给引用类型值动态地添加属性，以便将来使用。(给基本类型的添加了也是 undefined)</p>
<a id="more"></a>
<h2 id="复制变量值"><a href="#复制变量值" class="headerlink" title="复制变量值"></a>复制变量值</h2><p>基本类型：如果从一个变量向另一个变量复制基本类型的值，会在变量对象上创建一个新值，然后把该值复制到为新变量分配的位置上。<br>引用类型：当从一个变量向另一个变量复制引用类型的值时，同样也会将存储在变量对象中的值复制一份放到为新变量分配的空间中。不同的是，这个值的副本实际上是一个指针，而这个指针指向存储在堆中的一个对象。</p>
<h2 id="传递参数"><a href="#传递参数" class="headerlink" title="传递参数"></a>传递参数</h2><p>ECMAScript 中所有函数的参数都是按值传递的。<br>有不少开发人员在这一点上可能会感到困惑，因为访问变量有按值和按引用两种方式，而参数只能按值传递。</p>
<p>基本类型：在向参数传递基本类型的值时，被传递的值会被复制给一个局部变量(即命名参数，或者用 ECMAScript 的概念来说，就是 arguments 对象中的一个元素)。<br>引用类型：在向参数传递引用类型的值时，会把这个值在内存中的地址(引用/指针)复制给一个局部变量，因此这个局部变量的变化会反映在函数的外部(引用类型的值会被修改)。</p>
<p>有很多开发人员错误地认为：在局部作用域中修改的对象会在全局作用域中反映出来，就说明参数是按引用传递的。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">setName</span>(<span class="params">obj</span>) </span>&#123;</div><div class="line">    obj.name = <span class="string">"Nicholas"</span>;</div><div class="line">    obj = <span class="keyword">new</span> <span class="built_in">Object</span>();</div><div class="line">    obj.name = <span class="string">"Greg"</span>;</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> person = <span class="keyword">new</span> <span class="built_in">Object</span>();</div><div class="line">setName(person);</div><div class="line">alert(person.name); <span class="comment">//"Nicholas"</span></div></pre></td></tr></table></figure>
<p>如果 person 是按引用传递的，那么 person 就会自动被修改为指向其 name 属性值为 “Greg” 的新对象。<br>但是，当接下来再访问 person.name 时，显示的值仍然是 “Nicholas” 。<br>这说明即使在函数内部修改了参数的值，但<strong>原始的引用仍然保持未变</strong>。<br>实际上，当在函数内部重写 obj 时，这个变量引用的就是另一个对象，一个局部对象了。<br>而这个局部对象会在函数执行完毕后立即被销毁。<br>可以把 ECMAScript 函数的参数想象成局部变量。</p>
<h2 id="检测类型"><a href="#检测类型" class="headerlink" title="检测类型"></a>检测类型</h2><p>typeof:检测基本数据类型时 typeof 是非常得力的助手，但在检测引用类型的值时，这个操作符的用处不大。<br>instanceof:如果变量是给定引用类型的实例，那么 instanceof 操作符就会返回 true 。如果使用 instanceof 操作符检测基本类型的值，则该操作符始终会返回 false ，因为基本类型不是对象。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">alert(person <span class="keyword">instanceof</span> <span class="built_in">Object</span>);  <span class="comment">// 变量 person 是 Object 吗？</span></div><div class="line">alert(colors <span class="keyword">instanceof</span> <span class="built_in">Array</span>); <span class="comment">// 变量 colors 是 Array 吗？</span></div><div class="line">alert(pattern <span class="keyword">instanceof</span> <span class="built_in">RegExp</span>); <span class="comment">// 变量 pattern 是 RegExp 吗？</span></div></pre></td></tr></table></figure>
<p>使用 typeof 操作符检测函数时，该操作符会返回 “function” 。<br>ECMA-262 规定任何在内部实现 [[Call]] 方法的对象都应该在应用 typeof 操作符时返回 “function” 。<br>(在 Safari 5 及之前版本和 Chrome 7 及之前版本中使用 typeof 检测正则表达式时，浏览器中的正则表达式也实现了这个方法，因此对正则表达式应用 typeof 会返回 “function” )<br>(在 IE 和 Firefox 中，对正则表达式应用 typeof 会返回 “object”)</p>
<h1 id="执行环境及作用域"><a href="#执行环境及作用域" class="headerlink" title="执行环境及作用域"></a>执行环境及作用域</h1><h2 id="全局执行环境"><a href="#全局执行环境" class="headerlink" title="全局执行环境"></a>全局执行环境</h2><p><strong>全局执行环境</strong>是最外围的一个执行环境。根据 ECMAScript 实现所在的宿主环境不同，表示执行环境的对象也不一样。在 Web 浏览器中，全局执行环境被认为是 window 对象，因此所有全局变量和函数都是作为 window 对象的属性和方法创建的。(全局执行环境直到应用程序退出——例如关闭网页或浏览器——时才会被销毁)</p>
<h2 id="执行流"><a href="#执行流" class="headerlink" title="执行流"></a>执行流</h2><p>ECMAScript 程序中的<strong>执行流</strong>的控制机制：每个函数都有自己的执行环境。当执行流进入一个函数时，函数的环境就会被推入一个环境栈中。而在函数执行之后，栈将其环境弹出，把控制权返回给之前的执行环境。</p>
<h2 id="作用域链"><a href="#作用域链" class="headerlink" title="作用域链"></a>作用域链</h2><p>当代码在一个环境中执行时，会创建变量对象的一个<strong>作用域链</strong>(scope chain)。<br>每次进入一个新执行环境，都会创建一个用于搜索变量和函数的作用域链。</p>
<p>用途：是保证对执行环境有权访问的所有变量和函数的有序访问。</p>
<p>当前的变量对象——&gt;<br>活动对象作为变量对象(环境若是函数)——&gt;<br>活动对象最开始只包含 arguments 对象——&gt;<br>下一个变量对象来自包含(外部)环境——&gt;<br>再下一个来自下一个包含(外部)环境——&gt;<br>……<br>直到全局执行环境。</p>
<p>标识符(name)解析是沿着作用域链一级一级地搜索标识符的过程。(如果找不到标识符，通常会导致错误发生)</p>
<p>函数参数也被当作变量来对待，因此其访问规则与执行环境中的其他变量相同。</p>
<h3 id="延长作用域链"><a href="#延长作用域链" class="headerlink" title="延长作用域链"></a>延长作用域链</h3><ol>
<li>try-catch 语句的 catch 块；</li>
<li>with 语句。</li>
</ol>
<p>这两个语句都会在作用域链的前端添加一个变量对象。<br>对 with 语句来说，会将指定的对象添加到作用域链中。<br>对 catch 语句来说，会创建一个新的变量对象，其中包含的是被抛出的错误对象的声明。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">buildUrl</span>(<span class="params"></span>) </span>&#123;</div><div class="line">    <span class="keyword">var</span> qs = <span class="string">"?debug=true"</span>;</div><div class="line">    <span class="keyword">with</span>(location)&#123;</div><div class="line">        <span class="keyword">var</span> url = href + qs;</div><div class="line">    &#125;</div><div class="line">    <span class="keyword">return</span> url;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>url 成了函数执行环境中的一部分，所以可以当作函数的值被返回。</p>
<p>旧浏览器的 BUG :<br>在 IE8 及之前版本的 JavaScript 实现中，存在一个与标准不一致的地方，<br>即在 catch 语句中捕获的错误对象会被添加到执行环境的变量对象，而不是 catch 语句的变量对象中。<br>换句话说，即使是在 catch 块的外部也可以访问到错误对象。<br>IE9 修复了这个问题。</p>
<h3 id="没有块级作用域"><a href="#没有块级作用域" class="headerlink" title="没有块级作用域"></a>没有块级作用域</h3><p>例子：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">if</span> (<span class="literal">true</span>) &#123;</div><div class="line">    <span class="keyword">var</span> color = <span class="string">"blue"</span>;</div><div class="line">&#125;</div><div class="line">alert(color); <span class="comment">//"blue"</span></div></pre></td></tr></table></figure>
<p>如果是在 C 、 C++ 或 Java 中， color 会在 if 语句执行完毕后被销毁。<br>但在 JavaScript 中， if 语句中的变量声明会将变量添加到当前的执行环境(在这里是全局环境)中。<br>在使用 for 语句时尤其要牢记这一差异。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i=<span class="number">0</span>; i &lt; <span class="number">10</span>; i++)&#123;</div><div class="line">    doSomething(i);</div><div class="line">&#125;</div><div class="line">alert(i); <span class="comment">//10</span></div></pre></td></tr></table></figure>
<p>对于有块级作用域的语言来说， for 语句初始化变量的表达式所定义的变量，只会存在于循环的环境之中。<br>而对于 JavaScript 来说，由 for 语句创建的变量 i 即使在 for 循环执行结束后，也依旧会存在于循环外部的执行环境中。</p>
<ol>
<li>声明变量：<br> 使用 var 声明的变量会自动被添加到最接近的环境中。<br> 在函数内部，最接近的环境就是函数的局部环境；<br> 在 with 语句中，最接近的环境是函数环境。<br> 如果初始化变量时没有使用 var 声明，该变量会自动被添加到全局环境。<br> 要点：<br> 在编写 JavaScript 代码的过程中，不声明而直接初始化变量是一个常见的错误做法，因为这样可能会导致意外。<br> 我们建议在初始化变量之前，一定要先声明，这样就可以避免类似问题。<br> <strong>在严格模式下，初始化未经声明的变量会导致错误。</strong></li>
<li>查询标识符：<br> 如果存在一个局部的变量的定义，则搜索会自动停止，不再进入另一个变量对象。<br> 换句话说，如果局部环境中存在着同名标识符，就不会使用位于父环境中的标识符。<br> 变量查询也不是没有代价的。很明显，访问局部变量要比访问全局变量更快，因为不用向上搜索作用域链。<br> JavaScript 引擎在优化标识符查询方面做得不错，因此这个差别在将来恐怕就可以忽略不计了。</li>
</ol>
<h1 id="垃圾收集"><a href="#垃圾收集" class="headerlink" title="垃圾收集"></a>垃圾收集</h1><p>离开作用域的值将被自动标记为可以回收，因此将在垃圾收集期间被删除。<br>用于标识无用变量的策略可能会因实现而异，但具体到浏览器中的实现，则通常有两个策略。</p>
<h2 id="标记清除"><a href="#标记清除" class="headerlink" title="标记清除"></a>标记清除</h2><p>JavaScript 中最常用的垃圾收集方式(mark-and-sweep)。<br>当变量进入环境(例如，在函数中声明一个变量)时，就将这个变量标记为“进入环境”。<br>从逻辑上讲，永远不能释放进入环境的变量所占用的内存，因为只要执行流进入相应的环境，就可能会用到它们。<br>而当变量离开环境时，则将其标记为“离开环境”。<br>如何标记变量其实并不重要，关键在于采取什么策略。</p>
<p>垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记(当然，可以使用任何标记方式)。——[mark all]<br>然后，它会去掉环境中的变量以及被环境中的变量引用的变量的标记。——[delete used]<br>在此之后再被加上标记的变量将被视为准备删除的变量，原因是环境中的变量已经无法访问到这些变量了。——[mark garbage]<br>最后，垃圾收集器完成内存清除工作，销毁那些带标记的值并回收它们所占用的内存空间。——[swap]</p>
<p>到 2008 年为止， IE 、 Firefox 、 Opera 、 Chrome 和 Safari 的 JavaScript 实现使用的都是标记清除式的垃圾收集策略(或类似的策略)，只不过垃圾收集的时间间隔互有不同。</p>
<h2 id="引用计数"><a href="#引用计数" class="headerlink" title="引用计数"></a>引用计数</h2><p>另一种不太常见的垃圾收集策略。<br>含义是跟踪记录每个值被引用的次数。<br>当声明了一个变量并将一个引用类型值赋给该变量时，则这个值的引用次数就是 1。<br>如果同一个值又被赋给另一个变量，则该值的引用次数加 1。<br>相反，如果包含对这个值引用的变量又取得了另外一个值，则这个值的引用次数减 1。<br>当这个值的引用次数变成 0 时，则说明没有办法再访问这个值了，因而就可以将其占用的内存空间回收回来。<br>当垃圾收集器下次再运行时，它就会释放那些引用次数为零的值所占用的内存。</p>
<p>Netscape Navigator 3.0是最早使用引用计数策略的浏览器。</p>
<h3 id="严重问题：循环引用。"><a href="#严重问题：循环引用。" class="headerlink" title="严重问题：循环引用。"></a>严重问题：循环引用。</h3><p>所以 Netscape 在 Navigator 4.0 中放弃了引用计数方式，转而采用标记清除来实现其垃圾收集机制。<br>可是引用计数导致的麻烦并未就此终结。</p>
<p>IE 中有一部分对象并不是原生 JavaScript 对象。<br>例如，其 BOM 和 DOM 中的对象就是使用 C++以 COM(Component Object Model ，组件对象模型)对象的形式实现的，<br>而 COM 对象的垃圾收集机制采用的就是引用计数策略。<br>即使 IE 的 JavaScript 引擎是使用标记清除策略来实现的，<br>但 JavaScript 访问的 COM 对象依然是基于引用计数策略的。<br>换句话说，只要在 IE 中涉及 COM 对象，就会存在循环引用的问题。</p>
<p>例子：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> element = <span class="built_in">document</span>.getElementById(<span class="string">"some_element"</span>);</div><div class="line"><span class="keyword">var</span> myObject = <span class="keyword">new</span> <span class="built_in">Object</span>();</div><div class="line">myObject.element = element;</div><div class="line">element.someObject = myObject;</div></pre></td></tr></table></figure>
<p>这个例子在一个 DOM 元素( element )与一个原生 JavaScript 对象( myObject )之间创建了循环引用。<br>其中，变量 myObject 有一个名为 element 的属性指向 element 对象；<br>而变量 element 也有一个属性名叫 someObject 回指 myObject 。<br>由于存在这个循环引用，即使将例子中的 DOM 从页面中移除，它也永远不会被回收。</p>
<p>为了避免类似这样的循环引用问题，最好是在不使用它们的时候手工断开原生 JavaScript 对象与 DOM 元素之间的连接。<br>例如可以使用下面的代码消除前面例子创建的循环引用：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">myObject.element = <span class="literal">null</span>;</div><div class="line">element.someObject = <span class="literal">null</span>;</div></pre></td></tr></table></figure>
<p>将变量设置为 null 意味着切断变量与它此前引用的值之间的连接。当垃圾收集器下次运行时，就会删除这些值并回收它们占用的内存。</p>
<p>在 IE9 时把 BOM 和 DOM 对象都转换成了真正的 JavaScript 对象。这样，就避免了两种垃圾收集算法并存导致的问题，也消除了常见的内存泄漏现象。</p>
<h2 id="性能问题"><a href="#性能问题" class="headerlink" title="性能问题"></a>性能问题</h2><h3 id="IE-声名狼藉的性能问题。"><a href="#IE-声名狼藉的性能问题。" class="headerlink" title="IE 声名狼藉的性能问题。"></a>IE 声名狼藉的性能问题。</h3><p>IE 的垃圾收集器是根据内存分配量运行的，<br>具体一点说就是 256 个变量、4096 个对象(或数组)字面量和数组元素(slot)或者 64KB 的字符串。<br>达到上述任何一个临界值，垃圾收集器就会运行。</p>
<p>问题在于，如果一个脚本中包含那么多变量，那么该脚本很可能会在其生命周期中一直保有那么多的变量。<br>而这样一来，垃圾收集器就不得不频繁地运行。</p>
<p>由此引发的严重性能问题促使 IE7 重写了其垃圾收集例程。<br>IE7触发垃圾收集的变量分配、字面量和(或)数组元素的临界值被调整为动态修正。</p>
<p>临界值在初始时与 IE6 相等。<br>如果垃圾收集例程回收的内存分配量低于 15%，则临界值加倍。<br>如果例程回收了 85%的内存分配量，则将各种临界值重置回默认值。</p>
<p><strong>事实上，在有的浏览器中可以触发垃圾收集过程，但我们不建议读者这样做。</strong>在 IE 中，调用 window.CollectGarbage() 方法会立即执行垃圾收集。</p>
<h1 id="管理内存"><a href="#管理内存" class="headerlink" title="管理内存"></a>管理内存</h1><p>JavaScript 在进行内存管理及垃圾收集时面临的问题还是有点与众不同。</p>
<p>最主要的一个问题，就是分配给 Web 浏览器的可用内存数量通常要比分配给桌面应用程序的少。<br>目的是防止运行 JavaScript 的网页耗尽全部系统内存而导致系统崩溃。<br><strong>内存限制问题</strong>不仅会影响给变量分配内存，同时还会影响调用栈以及在一个线程中能够同时执行的语句数量。</p>
<p>优化内存占用的最佳方式，就是为执行中的代码只保存必要的数据。<br>一旦数据不再有用，最好通过将其值设置为 null 来释放其引用——这个做法叫做解除引用(dereferencing)。<br>这一做法适用于大多数全局变量和全局对象的属性。<br>局部变量会在它们离开执行环境时自动被解除引用。</p>
<p>解除一个值的引用并不意味着自动回收该值所占用的内存。<br>解除引用的真正作用是让值脱离执行环境，以便垃圾收集器下次运行时将其回收。<br>为了确保有效地回收内存，应该及时解除不再使用的全局对象、全局对象属性以及循环引用变量的引用。</p>

      
    </div>

    <div>
      
        

      
    </div>

    <div>
      
        

      
    </div>


    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/Web/" rel="tag"># Web</a>
          
            <a href="/tags/JavaScript/" rel="tag"># JavaScript</a>
          
        </div>
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2016/09/17/javascript-note-03-3/" rel="next" title="《 JavaScript 高级程序设计》备忘-第三章-3">
                <i class="fa fa-chevron-left"></i> 《 JavaScript 高级程序设计》备忘-第三章-3
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2016/09/17/javascript-note-05-1/" rel="prev" title="《 JavaScript 高级程序设计》备忘-第五章-1">
                《 JavaScript 高级程序设计》备忘-第五章-1 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          
  <div class="comments" id="comments">
    
  </div>


        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/uploads/avatar.jpg"
               alt="Huang SJ" />
          <p class="site-author-name" itemprop="name">Huang SJ</p>
          <p class="site-description motion-element" itemprop="description"></p>
        </div>
        <nav class="site-state motion-element">
          <div class="site-state-item site-state-posts">
            <a href="/archives">
              <span class="site-state-item-count">75</span>
              <span class="site-state-item-name">日志</span>
            </a>
          </div>

          
            <div class="site-state-item site-state-categories">
              <a href="/categories">
                <span class="site-state-item-count">4</span>
                <span class="site-state-item-name">分类</span>
              </a>
            </div>
          

          
            <div class="site-state-item site-state-tags">
              <a href="/tags">
                <span class="site-state-item-count">9</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        

        <div class="links-of-author motion-element">
          
            
              <span class="links-of-author-item">
                <a href="https://github.com/hsj1992" target="_blank" title="GitHub">
                  
                    <i class="fa fa-fw fa-github"></i>
                  
                  GitHub
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://twitter.com/hsj9527" target="_blank" title="Twitter">
                  
                    <i class="fa fa-fw fa-twitter"></i>
                  
                  Twitter
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://weibo.com/u/1694147905" target="_blank" title="Weibo">
                  
                    <i class="fa fa-fw fa-weibo"></i>
                  
                  Weibo
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://www.freecodecamp.cn/hsj1992" target="_blank" title="FreeCodeCamp">
                  
                    <i class="fa fa-fw fa-fire"></i>
                  
                  FreeCodeCamp
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://codepen.io/hsj1992/" target="_blank" title="codepen">
                  
                    <i class="fa fa-fw fa-codepen"></i>
                  
                  codepen
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://hsj1992.oschina.io/" target="_blank" title="码云镜像">
                  
                    <i class="fa fa-fw fa-code"></i>
                  
                  码云镜像
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://hsj1992.coding.me/" target="_blank" title="coding镜像">
                  
                    <i class="fa fa-fw fa-code"></i>
                  
                  coding镜像
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://hsj1992.github.io/" target="_blank" title="github镜像">
                  
                    <i class="fa fa-fw fa-code"></i>
                  
                  github镜像
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://codingme-6dd8a.firebaseapp.com" target="_blank" title="Firebase镜像">
                  
                    <i class="fa fa-fw fa-google"></i>
                  
                  Firebase镜像
                </a>
              </span>
            
          
        </div>

        
        

        
        

        


      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#基本类型和引用类型的值"><span class="nav-number">1.</span> <span class="nav-text">基本类型和引用类型的值</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#动态的属性"><span class="nav-number">1.1.</span> <span class="nav-text">动态的属性</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#复制变量值"><span class="nav-number">1.2.</span> <span class="nav-text">复制变量值</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#传递参数"><span class="nav-number">1.3.</span> <span class="nav-text">传递参数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#检测类型"><span class="nav-number">1.4.</span> <span class="nav-text">检测类型</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#执行环境及作用域"><span class="nav-number">2.</span> <span class="nav-text">执行环境及作用域</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#全局执行环境"><span class="nav-number">2.1.</span> <span class="nav-text">全局执行环境</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#执行流"><span class="nav-number">2.2.</span> <span class="nav-text">执行流</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#作用域链"><span class="nav-number">2.3.</span> <span class="nav-text">作用域链</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#延长作用域链"><span class="nav-number">2.3.1.</span> <span class="nav-text">延长作用域链</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#没有块级作用域"><span class="nav-number">2.3.2.</span> <span class="nav-text">没有块级作用域</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#垃圾收集"><span class="nav-number">3.</span> <span class="nav-text">垃圾收集</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#标记清除"><span class="nav-number">3.1.</span> <span class="nav-text">标记清除</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#引用计数"><span class="nav-number">3.2.</span> <span class="nav-text">引用计数</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#严重问题：循环引用。"><span class="nav-number">3.2.1.</span> <span class="nav-text">严重问题：循环引用。</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#性能问题"><span class="nav-number">3.3.</span> <span class="nav-text">性能问题</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#IE-声名狼藉的性能问题。"><span class="nav-number">3.3.1.</span> <span class="nav-text">IE 声名狼藉的性能问题。</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#管理内存"><span class="nav-number">4.</span> <span class="nav-text">管理内存</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy;  2015 - 
  <span itemprop="copyrightYear">2016</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Huang SJ</span>
</div>


<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.Pisces
  </a>
</div>


        

        
      </div>
    </footer>

    <div class="back-to-top">
      <i class="fa fa-arrow-up"></i>
    </div>
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  



  
  <script type="text/javascript" src="//cdn.staticfile.org/jquery/2.1.3/jquery.min.js"></script>

  
  <script type="text/javascript" src="//cdn.staticfile.org/fastclick/1.0.6/fastclick.min.js"></script>

  
  <script type="text/javascript" src="//cdn.staticfile.org/jquery_lazyload/1.9.7/jquery.lazyload.min.js"></script>

  
  <script type="text/javascript" src="//cdn.staticfile.org/velocity/1.2.1/velocity.min.js"></script>

  
  <script type="text/javascript" src="//cdn.staticfile.org/velocity/1.2.1/velocity.ui.min.js"></script>

  
  <script type="text/javascript" src="//cdn.staticfile.org/fancybox/2.1.5/jquery.fancybox.pack.js"></script>


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.0"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.0"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.0"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.0"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.0"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.0"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.0"></script>



  



  




	




  
  
  <script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    // Search DB path;
    var search_path = "search.xml";
    if (search_path.length == 0) {
      search_path = "search.xml";
    }
    var path = "/" + search_path;
    // monitor main search box;

    function proceedsearch() {
      $("body").append('<div class="popoverlay">').css('overflow', 'hidden');
      $('.popup').toggle();
    }
    // search function;
    var searchFunc = function(path, search_id, content_id) {
      'use strict';
      $.ajax({
        url: path,
        dataType: "xml",
        async: true,
        success: function( xmlResponse ) {
          // get the contents from search data
          isfetched = true;
          $('.popup').detach().appendTo('.header-inner');
          var datas = $( "entry", xmlResponse ).map(function() {
            return {
              title: $( "title", this ).text(),
              content: $("content",this).text(),
              url: $( "url" , this).text()
            };
          }).get();
          var $input = document.getElementById(search_id);
          var $resultContent = document.getElementById(content_id);
          $input.addEventListener('input', function(){
            var matchcounts = 0;
            var str='<ul class=\"search-result-list\">';
            var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
            $resultContent.innerHTML = "";
            if (this.value.trim().length > 1) {
              // perform local searching
              datas.forEach(function(data) {
                var isMatch = false;
                var content_index = [];
                var data_title = data.title.trim().toLowerCase();
                var data_content = data.content.trim().replace(/<[^>]+>/g,"").toLowerCase();
                var data_url = decodeURIComponent(data.url);
                var index_title = -1;
                var index_content = -1;
                var first_occur = -1;
                // only match artiles with not empty titles and contents
                if(data_title != '') {
                  keywords.forEach(function(keyword, i) {
                    index_title = data_title.indexOf(keyword);
                    index_content = data_content.indexOf(keyword);
                    if( index_title >= 0 || index_content >= 0 ){
                      isMatch = true;
                      if (i == 0) {
                        first_occur = index_content;
                      }
                    }

                  });
                }
                // show search results
                if (isMatch) {
                  matchcounts += 1;
                  str += "<li><a href='"+ data_url +"' class='search-result-title'>"+ data_title +"</a>";
                  var content = data.content.trim().replace(/<[^>]+>/g,"");
                  if (first_occur >= 0) {
                    // cut out 100 characters
                    var start = first_occur - 20;
                    var end = first_occur + 80;
                    if(start < 0){
                      start = 0;
                    }
                    if(start == 0){
                      end = 50;
                    }
                    if(end > content.length){
                      end = content.length;
                    }
                    var match_content = content.substring(start, end);
                    // highlight all keywords
                    keywords.forEach(function(keyword){
                      var regS = new RegExp(keyword, "gi");
                      match_content = match_content.replace(regS, "<b class=\"search-keyword\">"+keyword+"</b>");
                    });

                    str += "<p class=\"search-result\">" + match_content +"...</p>"
                  }
                  str += "</li>";
                }
              })};
            str += "</ul>";
            if (matchcounts == 0) { str = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>' }
            if (keywords == "") { str = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>' }
            $resultContent.innerHTML = str;
          });
          proceedsearch();
        }
      });}

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched == false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });

    $('.popup-btn-close').click(function(e){
      $('.popup').hide();
      $(".popoverlay").remove();
      $('body').css('overflow', '');
    });
    $('.popup').click(function(e){
      e.stopPropagation();
    });
  </script>


  

  

  

  


</body>
</html>
